/*
 * Created by: Vadik Vaksin
 * Created: Monday, February 27, 2006
 */

using System;
using System.Collections;
using System.Globalization;
using System.Reflection;
using fit;

namespace TestUtils
{
	public class DynamicDefinitionFixture : KeyedDefinitionFixture
	{
		Hashtable values = new Hashtable();

		protected override void CreateFieldsArray()
		{
			// do nothing, we don't need this here
		}

		protected override TypeAdapter bindField(string name)
		{
			string camelName = camel(name);
			values.Add(camelName, null);
			FieldInfo fieldInfo = new DynamicDefinitionFixtureFieldInfo(camelName);
			AddFieldToFieldsArray(fieldInfo);			
			return TypeAdapter.on(this, fieldInfo);
		}

		public Hashtable Values
		{
			get {return values;}
			set {values = value;}
		}
	}

	class DynamicDefinitionFixtureFieldInfo: FieldInfo {
		readonly string name;

		public DynamicDefinitionFixtureFieldInfo(string name) : base()
		{
			this.name = name;
		}
		
		DynamicDefinitionFixture GetDynamicDefinitionFixture(object obj)
		{
			DynamicDefinitionFixture dynamicDefinitionFixture = obj as DynamicDefinitionFixture;
			if (dynamicDefinitionFixture == null)
				throw new ApplicationException("<obj> should be of DynamicDefinitionFixture type");
			return dynamicDefinitionFixture;
		}

		void ValidateField(DynamicDefinitionFixture dynamicDefinitionFixture)
		{
			if (!dynamicDefinitionFixture.Values.ContainsKey(name))
				throw new ApplicationException("Field " + name + "not exists in provided object");
		}
		
		public override object GetValue(object obj)
		{
			DynamicDefinitionFixture dynamicDefinitionFixture = GetDynamicDefinitionFixture(obj);
			ValidateField(dynamicDefinitionFixture);
			return dynamicDefinitionFixture.Values[name];
		}

		public override void SetValue(object obj, object value, BindingFlags invokeAttr, Binder binder, CultureInfo culture)
		{
			DynamicDefinitionFixture dynamicDefinitionFixture = GetDynamicDefinitionFixture(obj);
			ValidateField(dynamicDefinitionFixture);
			dynamicDefinitionFixture.Values[name] = value;
		}

		public override RuntimeFieldHandle FieldHandle
		{
			get {throw new NotImplementedException();}
		}

		public override Type FieldType
		{
			get {return typeof(string);}
		}

		public override FieldAttributes Attributes
		{
			get {throw new NotImplementedException();}
		}

		public override object[] GetCustomAttributes(bool inherit)
		{
			throw new NotImplementedException();
		}

		public override object[] GetCustomAttributes(Type attributeType, bool inherit)
		{
			throw new NotImplementedException();
		}

		public override bool IsDefined(Type attributeType, bool inherit)
		{
			throw new NotImplementedException();
		}

		public override string Name
		{
			get {return name;}
		}

		public override Type DeclaringType
		{
			get {return typeof(DynamicDefinitionFixture);}
		}

		public override Type ReflectedType
		{
			get {throw new NotImplementedException();}
		}
	}
}